package com.redlion;

import java.util.ArrayList;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.scene.IOnAreaTouchListener;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.ITouchArea;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.text.Text;
import org.andengine.entity.text.TextOptions;
import org.andengine.entity.util.FPSLogger;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.extension.physics.box2d.util.Vector2Pool;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.BuildableBitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.source.IBitmapTextureAtlasSource;
import org.andengine.opengl.texture.atlas.buildable.builder.BlackPawnTextureAtlasBuilder;
import org.andengine.opengl.texture.atlas.buildable.builder.ITextureAtlasBuilder.TextureAtlasBuilderException;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.texture.region.TextureRegion;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.util.HorizontalAlign;
import org.andengine.util.debug.Debug;
import org.andengine.util.math.MathUtils;

import android.graphics.Color;
import android.graphics.Typeface;
import android.util.Log;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.redlion.hud.MyHUD;
import com.redlion.hud.OnCatalogItemClickListener;
import com.redlion.hud.MyHUD.SLOT;
import com.redlion.object.LaserStrokePool;
import com.redlion.object.Planet;
import com.redlion.object.ShotPool;
import com.redlion.weapon.Cannon;
import com.redlion.weapon.LaserStroke;
import com.redlion.weapon.OnFireListener;
import com.redlion.weapon.PlayerWeapon;
import com.redlion.weapon.UpdateTaskListener;
import com.redlion.weapon.Upgrade;
import com.redlion.weapon.WeaponAdapter;
import com.redlion.weapon.WeaponCatalog;
import com.redlion.weapon.WeaponEntry;

public class StartScene implements IAccelerationListener, OnCatalogItemClickListener, IUpdateHandler, UpdateTaskListener,
		IOnSceneTouchListener, OnFireListener {
	private static final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);

	public static Scene mScene;

	private Planet planet;
	private Text mLoadingText;

	private Cannon mULcannon;

	private Cannon mURcannon;

	private Cannon mLLcannon;

	private Cannon mLRcannon;

	private MyHUD mHud;

	private GameActivity base;
	public static ArrayList<UpdateTask> tasks = new ArrayList<UpdateTask>();

	public BuildableBitmapTextureAtlas mBitmapTextureAtlas;
	public ITextureRegion mPlanetTextureRegion;
	public ITextureRegion mCometTextureRegion;
	public ITextureRegion mLaserWeaponRegion;
	public ITiledTextureRegion mWeapons_TTR;
	public TiledTextureRegion mAnimatedCometRegion;
	public BitmapTextureAtlas mAutoParallaxBackgroundTexture;
	public ITextureRegion mParallaxLayerBack;
	public TiledTextureRegion mAnimatedImpactRegion;
	public TiledTextureRegion mPlayerLaser_TTR;
	public Font mFont;
	public TextureRegion mBullet_TR;
	public TextureRegion mCrosshair_TR;
	public BuildableBitmapTextureAtlas mTextureAtlas;
	public TextureRegion mHUD_WeaponSlot_TR;
	public TiledTextureRegion mHUD_ToogleSlotsButton_TTR;
	public TextureRegion mHUD_CatalogItemBackground_TR;
	public BitmapTextureAtlas mWeaponTextureAtlas;

	private Sprite mCrosshairSprite;

	private float chW;

	private float chH;

	private Sprite mTargetSprite;

	private TextureRegion mTarget_TR;

	private PlayerWeapon mPlayerWeapon;

	public StartScene(GameActivity base) {
		this.base = base;
		onCreateResources();
	}

	public void onCreateResources() {

		mTextureAtlas = new BuildableBitmapTextureAtlas(base.getTextureManager(), 1024, 1024);
		mPlanetTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTextureAtlas, base, "planet_128.png");
		mHUD_WeaponSlot_TR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTextureAtlas, base, "slot.png");
		mHUD_ToogleSlotsButton_TTR = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTextureAtlas, base, "slot_button.png", 2,
				1);
		mWeapons_TTR = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTextureAtlas, base, "weapon_TA.png", 2, 4);
		mPlayerLaser_TTR = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTextureAtlas, base, "p_laser_4.png", 2, 2);
		mBullet_TR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTextureAtlas, base, "laser_bullet.png");
		mCrosshair_TR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTextureAtlas, base, "crosshair.png");
		mTarget_TR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mTextureAtlas, base, "comet_32.png");
		try {
			mTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 0, 0));
			mTextureAtlas.load();

		} catch (TextureAtlasBuilderException e) {
			Debug.e(e);
		}

		mWeaponTextureAtlas = new BitmapTextureAtlas(base.getTextureManager(), 1, 128, TextureOptions.REPEATING_NEAREST);
		mHUD_CatalogItemBackground_TR = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mWeaponTextureAtlas, base,
				"weapon_slot.png", 0, 0);
		mHUD_CatalogItemBackground_TR.setTextureWidth(this.mWeaponTextureAtlas.getWidth());
		mWeaponTextureAtlas.load();

		mFont = FontFactory.create(base.getFontManager(), base.getTextureManager(), 256, 256,
				Typeface.create(Typeface.DEFAULT, Typeface.NORMAL), 16, Color.WHITE);
		mFont.load();
		WeaponCatalog.bindAnimationTexture(WeaponCatalog.WEAPON_LASER, mWeapons_TTR, new int[] { 0, 1, 2, 3 }, 0);
		WeaponCatalog.bindAnimationTexture(WeaponCatalog.WEAPON_DEBUG, mWeapons_TTR, new int[] { 4, 5, 6, 7 }, 4);
	}

	public Scene onCreateScene() {
		base.getEngine().registerUpdateHandler(new FPSLogger());
		mScene = new Scene();
		PhysicsWorld mPhysicsWorld = new PhysicsWorld(new Vector2(0, 0), false);
		Game.getInstance().registerPhysics(mPhysicsWorld);
		Game.getInstance().registerScene(mScene);

		planet = new Planet(Game.CAMERA_WIDTH * 0.5f, Game.CAMERA_HEIGHT * 0.5f);
		planet.createSprite(mPlanetTextureRegion);
		planet.enableRotation(Planet.ROTATION_DURATION);

		mScene.attachChild(planet.sprite);
		Game.getInstance().registerPlanet(planet);

		mLoadingText = new Text(Game.CAMERA_WIDTH * 0.5f, Game.CAMERA_HEIGHT * 0.5f, mFont, "Loading...", new TextOptions(
				HorizontalAlign.CENTER), base.getVertexBufferObjectManager());
		mLoadingText.setPosition(mLoadingText.getX() - mLoadingText.getWidth() * 0.5f, Game.CAMERA_HEIGHT * 0.5f + 100);
		mScene.attachChild(mLoadingText);

		createWeapons(planet);

		mHud = new MyHUD(mFont, base);
		// mHud.createInterface(mHUD_WeaponSlot_TR, mHUD_ToogleSlotsButton_TTR,
		// mHUD_CatalogItemBackground_TR, mScene, planet.sprite);
		// mHud.registerListener(this);
		// mHud.bindCatalogEntryToSlot(SLOT.UPPER_LEFT, new
		// WeaponAdapter(mULcannon, mFont,mHUD_CatalogItemBackground_TR));
		// mHud.bindCatalogEntryToSlot(SLOT.UPPER_RIGHT, new
		// WeaponAdapter(mURcannon, mFont,mHUD_CatalogItemBackground_TR));
		// mHud.bindCatalogEntryToSlot(SLOT.LOWER_LEFT, new
		// WeaponAdapter(mLLcannon, mFont,mHUD_CatalogItemBackground_TR));
		// mHud.bindCatalogEntryToSlot(SLOT.LOWER_RIGHT, new
		// WeaponAdapter(mLRcannon, mFont,mHUD_CatalogItemBackground_TR));

		Game.pools.bulletPool = new ShotPool(mBullet_TR, FIXTURE_DEF);
		Game.pools.laserStrokePool = new LaserStrokePool(mScene);
		mScene.registerUpdateHandler(mPhysicsWorld);
		mScene.registerUpdateHandler(this);

		mCrosshairSprite = new Sprite(0, 0, mCrosshair_TR, base.getVertexBufferObjectManager());
		mScene.attachChild(mCrosshairSprite);
		mCrosshairSprite.setVisible(false);
		chW = mCrosshairSprite.getWidth() / 2;
		chH = mCrosshairSprite.getHeight() / 2;

		mTargetSprite = new Sprite(400, 10, mTarget_TR, base.getVertexBufferObjectManager());
		mScene.attachChild(mTargetSprite);

		mScene.setOnSceneTouchListener(this);
		WeaponCatalog.registerUpdateTaskListener(this);

		mPlayerWeapon = new PlayerWeapon(planet.center, mPlayerLaser_TTR);
		mPlayerWeapon.setFireListener(this);
		mScene.attachChild(mPlayerWeapon.sprite);

		return mScene;
	}

	private void createWeapons(Planet pPlanet) {
		float x = pPlanet.sprite.getWidth() * 0.5f;
		float y = pPlanet.sprite.getHeight() * 0.5f;
		float offset = 80;
		Vector2 UL = Vector2Pool.obtain(-1, -1).nor().mul(offset).add(x, y);
		Vector2 UR = Vector2Pool.obtain(1, -1).nor().mul(offset).add(x, y);
		Vector2 LL = Vector2Pool.obtain(-1, 1).nor().mul(offset).add(x, y);
		Vector2 LR = Vector2Pool.obtain(1, 1).nor().mul(offset).add(x, y);

		mULcannon = new Cannon(UL, mWeapons_TTR);
		mULcannon.sprite.setRotation(225);
		mURcannon = new Cannon(UR, mWeapons_TTR);
		mURcannon.sprite.setRotation(315);
		mLLcannon = new Cannon(LL, mWeapons_TTR);
		mLLcannon.sprite.setRotation(135);
		mLRcannon = new Cannon(LR, mWeapons_TTR);
		mLRcannon.sprite.setRotation(45);
		// aniLaser.animate(WeaponCatalog.getWeapon(WeaponCatalog.LASER_CANNON).setup.getUpgrade(0));
		pPlanet.sprite.attachChild(mULcannon.sprite);
		pPlanet.sprite.attachChild(mURcannon.sprite);
		pPlanet.sprite.attachChild(mLLcannon.sprite);
		pPlanet.sprite.attachChild(mLRcannon.sprite);
		Game.getInstance().registerWeapon(mULcannon);
		Game.getInstance().registerWeapon(mURcannon);
		Game.getInstance().registerWeapon(mLLcannon);
		Game.getInstance().registerWeapon(mLRcannon);

	}

	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		Vector2 aimV = Vector2Pool.obtain(pSceneTouchEvent.getX(), pSceneTouchEvent.getY()).sub(planet.center).nor();
		mPlayerWeapon.updateRotation(aimV.cpy());
		switch (pSceneTouchEvent.getAction()) {
		case TouchEvent.ACTION_DOWN:
			aimV = aimV.mul(120f);
			mCrosshairSprite.setVisible(true);
			mCrosshairSprite.setPosition(planet.centerX - aimV.x - chW, planet.centerY - aimV.y - chH);
			Vector2Pool.recycle(aimV);
			mPlayerWeapon.animate(1);
			break;
		case TouchEvent.ACTION_MOVE:
			aimV = aimV.mul(120f);
			mCrosshairSprite.setVisible(true);
			mCrosshairSprite.setPosition(planet.centerX - aimV.x - chW, planet.centerY - aimV.y - chH);
			Vector2Pool.recycle(aimV);
			break;
		case TouchEvent.ACTION_UP:
			// mCrosshairSprite.setVisible(false);
			// aimV = aimV.mul(80f);
			// Vector2 start = Vector2Pool.obtain(planet.centerX - aimV.x,
			// planet.centerY - aimV.y);
			// aimV = aimV.mul(10f);
			// Vector2 end = Vector2Pool.obtain(planet.centerX - aimV.x,
			// planet.centerY - aimV.y);
			// final LaserStroke line =
			// Game.pools.laserStrokePool.obtainPoolItem();
			// line.setPosition(start.x, start.y, end.x, end.y);
			// if (mTargetSprite.collidesWith(line))
			// Log.d("Debug", "Collision erkannt!");
			mPlayerWeapon.stopAnimationAt(0);
			break;
		}

		return false;
	}

	@Override
	public void firePlanetCannon(Cannon cannon) {

	}

	@Override
	public void firePlayerWeapon(PlayerWeapon playerWeapon) {
		Vector2 aimV = Vector2Pool.obtain(playerWeapon.rotationVector).mul(80f);
		Vector2 start = Vector2Pool.obtain(planet.centerX - aimV.x, planet.centerY - aimV.y);
		aimV = aimV.mul(10f);
		Vector2 end = Vector2Pool.obtain(planet.centerX - aimV.x, planet.centerY - aimV.y);
		final LaserStroke line = Game.pools.laserStrokePool.obtainPoolItem();
		line.setPosition(start.x, start.y, end.x, end.y);
		Vector2Pool.recycle(aimV);
		Vector2Pool.recycle(start);
		Vector2Pool.recycle(end);
		if (mTargetSprite.collidesWith(line))
			killComet();
	}

	private void killComet() {
		float x = MathUtils.random(0, Game.CAMERA_WIDTH - 32);
		while (x > Game.CAMERA_WIDTH * 0.5f - 64 && x < Game.CAMERA_WIDTH * 0.5f + 64)
			x = MathUtils.random(0, Game.CAMERA_WIDTH - 32);
		float y = MathUtils.random(0, Game.CAMERA_HEIGHT - 32);
		while (y > Game.CAMERA_HEIGHT * 0.5f - 64 && y < Game.CAMERA_HEIGHT * 0.5f + 64)
			y = MathUtils.random(0, Game.CAMERA_HEIGHT - 32);
		mTargetSprite.setPosition(x, y);
	}

	@Override
	public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onAccelerationChanged(AccelerationData pAccelerationData) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onCatalogItemClick(SLOT s, WeaponEntry e, Upgrade u) {
	}

	@Override
	public void onUpdate(float pSecondsElapsed) {
		for (UpdateTask task : tasks) {
			task.run();
		}
		tasks.clear();
	}

	@Override
	public void onUpdateTask(UpdateTask updateTask) {
		tasks.add(updateTask);
	}

	@Override
	public void reset() {
		// TODO Auto-generated method stub

	}

}
